package org.omnifaces.test;

import static java.util.logging.Level.OFF;
import static java.util.logging.Logger.getLogger;
import static org.apache.commons.logging.LogFactory.getFactory;

import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.CSSParseException;
import org.w3c.css.sac.ErrorHandler;

import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlHtml;

public class SilentHtmlUnitDriver extends HtmlUnitDriver {
	
	static {
	    getFactory().setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");

		getLogger("com.gargoylesoftware").setLevel(OFF);
		getLogger("com.gargoylesoftware.htmlunit").setLevel(OFF); // anything to get this thing to be quiet
		getLogger("org.apache.commons").setLevel(OFF);
	}
	
	private static final SilentErrorHandler silentErrorHandler = new SilentErrorHandler();
	
	@Override
	public WebClient getWebClient() {
		WebClient webClient = super.getWebClient();
		webClient.setCssErrorHandler(silentErrorHandler);
		return webClient;
	}
	

	
	public static class SilentErrorHandler implements ErrorHandler {
        @Override
        public void warning(CSSParseException arg0) throws CSSException {

        }

        @Override
        public void fatalError(CSSParseException arg0) throws CSSException {

        }

        @Override
        public void error(CSSParseException arg0) throws CSSException {

        }
    }
	
	@Override
	protected void assertElementNotStale(HtmlElement element) {
		SgmlPage elementPage = element.getPage();
		Page currentPage = lastPage();

		if (!currentPage.equals(elementPage)) {
			throw new StaleElementReferenceException(
					"Element appears to be stale. Did you navigate away from the page that contained it? "
							+ " And is the current window focussed the same as the one holding this element?");
		}

		// We need to walk the DOM to determine if the element is actually
		// attached
		DomNode parentElement = element;
		while (parentElement != null && !(parentElement instanceof HtmlHtml)) {
			parentElement = parentElement.getParentNode();
		}

		if (parentElement == null) {
			throw new StaleElementReferenceException(
					"The element seems to be disconnected from the DOM. "
							+ " This means that a user cannot interact with it.");
		}
	}
	
	
	

}
